package MapBase.logic 
{
	import MapBase.logic.control.Entity.Entity;
	import MapBase.logic.control.Entity.EntityDepthDot;
	import MapBase.logic.control.xml.EntityFloorXML;
	import MapBase.logic.control.xml.MapXML;
	import MapBase.logic.decorate.floor.EntityFloor;
	import MapBase.logic.decorate.floor.GridFloor;
	import MapBase.logic.decorate.tile.EntityFloorTile;
	import MapBase.logic.decorate.tile.NormalTile;
	import MapBase.logic.decorate.tile.SelectTile;
	import MapBase.logic.struct.GridCell;
	import MapBase.logic.untils.MapConfig;
	import MapBase.logic.vo.MapBaseVO;
	
	import com.friendsofed.isometric.IsoObject;
	import com.friendsofed.isometric.IsoUtils;
	import com.friendsofed.isometric.IsoWorld;
	import com.friendsofed.isometric.Point3D;
	import com.friendsofed.isometric.PointExchange;
	import com.utils.astar.AStar;
	import com.utils.astar.Grid;
	
	import fl.controls.Label;
	
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.utils.Dictionary;

	public class MapBase
	{
		static public var vo : MapBaseVO = MapBaseVO.Instance;
		
		private var _bkLayer : Sprite;
		private var _gridLayer : Sprite;
		private var _objLayer : Sprite
		public var isoBkLayer : IsoObject;   	//背景�?
		public var isoGridLayer : IsoObject; 	//网格�?
		public var isoObjLayer : IsoObject;  	//对象�?
		public var curMouseObj : IsoObject;
		private var oldMouseObj : IsoObject;
		
		public var tileList : Object;
		public var objList : Object;
		
		public var grid  : Grid;
		public var buildFloor : Object;
		
		public var selectTile : Object;
		public var oldSelTile : Object;
		
		private var file : MapConfig;
		private var mapXML : MapXML;
		
		private var _eObj : Entity;
		
		private var _loadBox : Loader;
		private var _xml : XML;
		private var _entityXML : XML;
		public var mapData : Dictionary;
		public var srcList : Object;
		
		public var world : IsoWorld;
		
		public function MapBase()
		{
			
		}
		
		public function Init():void
		{	
			// SceneMapBase 	中		mapBase.world = XG.stageLayer.world;
			// MapEditSceneMed 	中		_mapBase.world = XG.stageLayer.world;
//			world = 		 new IsoWorld;
			reset();
			
			isoBkLayer = 	 new IsoObject(vo.entitySize);
			isoGridLayer =	 new IsoObject(vo.entitySize);
			isoObjLayer =	 new IsoObject(vo.entitySize);
			
			_bkLayer = 		 new Sprite;
			_gridLayer =	 new Sprite;
			_objLayer = 	 new Sprite;
			
			tileList = 		 new Object;
		
			isoBkLayer.addChild(_bkLayer);
			isoGridLayer.addChild(_gridLayer);
			
			world.addChildToFloor(isoBkLayer);
			world.addChildToFloor(isoGridLayer);
			
			isoGridLayer.mouseChildren = false;
			isoBkLayer.mouseChildren = false;
		}
		
		/**
		 * 添加物体到世界中
		 * @param obj
		 * @param id	阻挡Id  buildFloor.xml中 
		 * 
		 */
		public function addEntityToWorld(entity : Object,blockId : String = "") : void
		{
			var isoObj : IsoObject = new IsoObject(vo.entitySize);
			var p3 : Point3D = IsoUtils.screenToIso(new Point(world.mouseX - entity.width/2,world.mouseY - entity.height));
			
			if(vo.AlignGrid)
			{
				isoObj.x = int(p3.x/vo.tileSize)*vo.tileSize;
				isoObj.z = int(p3.z/vo.tileSize)*vo.tileSize;
			}
			else
			{
				isoObj.x = p3.x;
				isoObj.z = p3.z;
			}
			
			isoObj.id = blockId;
			
			if(entity is IsoObject)
			{
				isoObj = entity as IsoObject;
			}
			else
			{
				isoObj.addChild(entity as DisplayObject);
			}

			writeEntityFloor(blockId,isoObj);
			
			world.addChildToWorld(isoObj);
			
//			world.sort();
		}
		
		/**删除实体**/
		public function delObjByMouse(evt : MouseEvent) : void
		{
			var isoObj : IsoObject = getMouseClickObj();
			
			if(isoObj)
			{
				world.removeChildFromWorld(isoObj);
			}
		}
		
		public function getObjFromObjLayer() : IsoObject
		{
			return null;
		}

		/**设置世界坐标**/
		public function setWorldLocation(worldX:Number,worldY:Number) : void
		{
			world.x = worldX;
			world.y = worldY;
		
			_bkLayer.x = -world.x;
		}

//========================================draw================================================================
		/**Tile打点状�?*/
		public function drawSelectTile(color : int = 0xFF0000) : void
		{
			new SelectTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,vo.mapType);
			selectTile["statu"] = 1;
		}
		
		/**Tile正常状�?*/
		public function drawNormalTile(color : int = 0x00FF00) : void
		{
			new NormalTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,vo.mapType);
			selectTile["statu"] = 0;
		}
		
		/**绘制实体阻挡**/
		public function trunDrawIsoObjFloor(color : int = 0x0000FF):void
		{
			if(selectTile["statu"]!=2)
			{
				selectTile["statu"] = 2;
				for(var i:int=selectTile["tile"].numChildren-1;i>=0;i--)
				{
					selectTile["tile"].removeChildAt(i);
				}
				var lab:Label = new Label;
				lab.text=curMouseObj.id;
				selectTile["tile"].addChild(lab);
				selectTile["ownId"] = curMouseObj.id;
				
				new EntityFloorTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,0x0000FF,vo.mapType);
				
			}else
			{
				for( i=selectTile["tile"].numChildren-1;i>=0;i--)
				{
					selectTile["tile"].removeChildAt(i);
				}
				
				if(selectTile.hasOwnProperty("ownId"))
				{
					delete selectTile["ownId"];	
				}
				selectTile["statu"] = 0;
				
				new NormalTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,vo.mapType);
			}
			
		}
		
		/**绘制背景**/
		public function drawBackGround():void
		{
			var bkLoad:Loader = new Loader;
			bkLoad.load(new URLRequest("assets/img/map/"+vo.bkMapName));
			
			_bkLayer.addChildAt(bkLoad,0);
			_bkLayer.x = -world.x;
		}
		
		public function turnDrawTile() : void
		{
			if( selectTile["statu"] == 0)
			{
				selectTile["statu"] = 1;
			
				new SelectTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,vo.mapType);
			}
			else if(selectTile["statu"] == 1)
			{
				selectTile["statu"] = 0;
				
				new NormalTile(selectTile["tile"],vo.tileSize*2,vo.tileSize,vo.mapType);
			}
		}
		
		/**绘制网格**/
		public function drawGrid(tileSize:int) : void
		{
			vo.tileSize = tileSize/2;
			
			var tileW : int = tileSize;
			var tileH : int = tileSize/2;
			
			for(var i:int=_gridLayer.numChildren-1;i>=0;i--)
			{
				_gridLayer.removeChildAt(i);
			}
			
			var gridFloor : GridFloor = new GridFloor(_gridLayer,grid,tileW,tileH,vo.mapType);
			
			tileList = gridFloor.tileList;
		}
//===========================================================================================================
		public function findPath():Array
		{
			grid.setStartNode(0,0);
			var atar : AStar = new AStar();
			atar.findPath(grid);
			return atar.path;
		}
		/**获取选中的Tile**/
		public function getSelectTile() : Sprite
		{
			return selectTile["tile"];
		}
		
		/**设置选中的Tile**/
		public function setSelectTile() : void
		{
			oldSelTile = selectTile;	
			
			var cell : GridCell = getMouseGridCell();
			
//			if(cell.x < 0 || cell.x>=this.rowNum || cell.y<0 || cell.y >=this.colNum)return;
			if(tileList.hasOwnProperty(cell.cellX+","+cell.cellY))
			selectTile = tileList[cell.cellX+","+cell.cellY];
			
			if(cell.cellX>=0 && cell.cellY>=0)
			{
				if(grid.getNode(cell.cellX,cell.cellY))
				{
					grid.getNode(cell.cellX,cell.cellY).walkable = !grid.getNode(cell.cellX,cell.cellY).walkable;
				}
			}
		}
		
		/**
		 * 获取当前鼠标所指的网格单元
		 * @return 网格单元
		 */		
		public function getMouseGridCell() : GridCell
		{
			var cell:GridCell = new GridCell;
			var sleX:int;
			var sleY:int; 
			
			if(vo.mapType == 1)
			{
				var p3 : Point3D = IsoUtils.screenToIso(new Point(world.mouseX,world.mouseY));
				sleX=Math.floor(p3.x/vo.tileSize);
				sleY=Math.floor(p3.z/vo.tileSize); 
				
				cell.x = p3.x;
				cell.y = p3.y;
				cell.z = p3.z;
			}
			else if(vo.mapType == 2)
			{
				var p : Point = PointExchange.StageToLogic(new Point(world.mouseX,world.mouseY));
				
//				sleX=Math.floor(p.x);
//				sleY=Math.floor(p.y); 
				sleX = p.x;
				sleY = p.y;
				
				cell.x = p.x;
				cell.z = p.y;
			}
			else if(vo.mapType == 3)
			{
				sleX=Math.floor(world.mouseX/vo.tileSize);
				sleY=Math.floor(world.mouseY/vo.tileSize);
				
				cell.x = world.mouseX;
				cell.z = world.mouseY;
			}
			
			cell.cellX = sleX;
			cell.cellY = sleY;
			
			return cell;
		}
		
		/**选中实体**/
		public function getMouseClickObj() : IsoObject
		{
			var returnObj : IsoObject;
			
			var hitArray : Array;
			hitArray = world.objects;
//			trace(world.getObjectsUnderPoint(new Point(world.stage.mouseX,world.stage.mouseY)));
			for(var i:int=0;i<hitArray.length;i++)
			{
				if(!(hitArray[i] is IsoObject))continue;
				
				var isoObj : IsoObject = hitArray[i];
			
				if(isoObj.hitTestPoint(world.stage.mouseX,world.stage.mouseY,true))
				{
					if(!returnObj)
					{
						returnObj = isoObj;
					}
					else
					{
						if(isoObj.depth > returnObj.depth)
						{	
//							if(world.stage.mouseX - isoObj.x> isoObj.width && isoObj.y-world.stage.mouseY> - isoObj.height)
							returnObj = isoObj;
						}
					}
				}
			}
			
			if(returnObj)
			{
				returnObj.graphics.clear();
				returnObj.graphics.lineStyle(0x000000,1);
				returnObj.graphics.drawRect(0,0,returnObj.width,returnObj.height);
				
				oldMouseObj = curMouseObj;
				if(oldMouseObj)
				{
					if(oldMouseObj != returnObj)
					{
						oldMouseObj.graphics.clear();
					}
				}
				curMouseObj = returnObj;
			}
			
			return returnObj;
		}
		
		/**创建网格**/
		public function createGrid(colNum:int,rowNum:int) : void
		{
			vo.numCols = colNum;
			vo.numRows = rowNum;
			
			grid = new Grid(colNum,rowNum);
		}
		
		/**打开地图文件**/
		public function open(callBackFun:Function=null):void
		{
			file  = new MapConfig;
			file.openConfig(openXMLCallBack);
			
			m_openBuUrCallFunction = null;
			if(callBackFun != null)
			{
				m_openBuUrCallFunction = callBackFun;
			}
		}
		
		/**
		 * 
		 * @param url
		 * example 			openByURL("assets/xml/mapData.xml"); 
		 */	
		private var  m_openBuUrCallFunction : Function;
		public function openByURL(url : String,callBackFun:Function=null,showGrid:Boolean=false):void
		{
			Init();
			
			file  = new MapConfig;
			file.openByURL(url,openXMLCallBack);
			
			m_openBuUrCallFunction = null;
			
			if(callBackFun != null)
			{
				m_openBuUrCallFunction = callBackFun;
			}
			
			if(showGrid)
			{
				isoGridLayer.visible = showGrid;
			}
			
//			isoGridLayer.visible = false;
		}
		
		private function openXMLCallBack() : void
		{
			_xml = file.mapXML;
			mapData = file.mapData;
			
			vo.numCols = mapData["colNum"]; 
			vo.numRows = mapData["rowNum"];
			vo.mapName = mapData["name"];
			vo.bkMapName = mapData["bkMapName"];
			vo.tileSize = mapData["tileSize"]/2;
			vo.mapType = mapData["type"];
			
			reset();
			
			addEntityFromMapData();
			
			grid = new Grid(vo.numCols,vo.numRows);
			
			var floorList : Array = mapData["floor"].split(",");
			
			for(var i:int=0;i<floorList.length;i++)
			{
				var c:int = i/vo.numCols;
				var r:int = i%vo.numRows;
				
				if(floorList[i] == 1)
				{
					grid.getNode(c,r).walkable = true;
				}
				else
				{
					grid.getNode(c,r).walkable = false;
				}
			}
			
			drawGrid( mapData["tileSize"]);
			drawBackGround();
			
			if(m_openBuUrCallFunction != null)
			{
				m_openBuUrCallFunction();
			}
		}
		
		private function addEntityFromMapData() : void
		{
			for each(var boxInfo : Object in mapData["isoBox"])
			{
				var loadBox : Loader = new Loader;
				var id : String = boxInfo["id"];
				loadBox.load(new URLRequest(srcList[id]["url"]));
				var isoObj : IsoObject = new IsoObject(vo.entitySize);
			
				if(vo.AlignGrid)
				{
					isoObj.x =  int(boxInfo["isoX"]/vo.tileSize)*vo.tileSize;
					isoObj.z =  int(boxInfo["isoZ"]/vo.tileSize)*vo.tileSize;
				}
				else
				{
					isoObj.x =  boxInfo["isoX"];
					isoObj.z =  boxInfo["isoZ"];
				}
				
				isoObj.id = boxInfo["id"];
				
				isoObj.addChild(loadBox);
				
				writeEntityFloor(id,isoObj);
				
				world.addChildToWorld(isoObj);
			}
			
			world.sort();
		}
		
		/**保存地图xml**/
		public function save() : void
		{			
			mapXML = new MapXML(grid,world,vo.mapType);
			
			mapXML.tileSize = vo.tileSize;
			mapXML.bkMapName = vo.bkMapName;
			
			mapXML.save();
		}
		
		/**保存地图xml**/
		public function saveEntityFloor() : void
		{	
			var xml:EntityFloorXML = new EntityFloorXML(world,this.tileList,vo.mapType);	
			xml.save();
		}
		
		public function updateCurMouseObj():void
		{
			var p2:Point=curMouseObj.localToGlobal(new Point(0,0));
			
			var p3 : Point3D = IsoUtils.screenToIso(new Point(world.mouseX - (curMouseObj.stage.mouseX-p2.x)
				,world.mouseY - (curMouseObj.stage.mouseY-p2.y)));
			
			if(vo.AlignGrid)
			{
				p3.x = int(p3.x/vo.tileSize)*vo.tileSize;
				p3.z = int(p3.z/vo.tileSize)*vo.tileSize;
			}
			
			curMouseObj.position = p3;	
			
			writeEntityFloor(curMouseObj.id,curMouseObj);
		}
		
		/**
		 * 重置
		 * **/
		public function reset() : void
		{
			//消灭对象
			world.reset();
			
			//消灭砖块
			if(tileList)
			{
				for each(var tile:Object in tileList)
				{
					_gridLayer.removeChild(tile["tile"]);
				}
			}
		
			tileList = new Object;
			
			//消灭背景
			if(_bkLayer)
			{
				for(var i:int=_bkLayer.numChildren-1;i>=0;i--)
				{
					_bkLayer.removeChildAt(i);
				}
			}
		}
		

		
		/**
		 *  显示实体地板
		 */		
		public function showEntityFloor():void
		{
			var objs:Array = world.objects;
			
			for(var i:int=0;i<objs.length;i++)
			{
				var isoObj : IsoObject = objs[i];
				isoObj.graphics.clear();
				var recs:Vector.<Rectangle> = isoObj.floor;
				
				var tileW : int = vo.tileSize*2;
				var tileH : int = vo.tileSize;
				
				new EntityFloor(isoObj,tileW,tileH,recs,vo.mapType);
			}
		}
		
		/**
		 * 隐藏实体地板 
		 */		
		public function hideEntityFloor():void
		{
			var objs:Array = world.objects;
			for(var i:int=0;i<objs.length;i++)
			{
				var isoObj : IsoObject = objs[i];
		
				isoObj.graphics.clear();
			}
		}
		
		/**
		 * 写入阻挡
		 * **/
		private function writeEntityFloor(type : String,isoObj: IsoObject):void
		{
			if(buildFloor.hasOwnProperty(type))
			{	
				var locatList : Array = buildFloor[type]["floor"].split(",");
				
				isoObj.floor = new Vector.<Rectangle>;
				
				for(var i:int = 0;i<locatList.length;i+=2)
				{
					var rec : Rectangle;
//					var ps : Point = IsoUtils.isoToScreen(new Point3D(isoObj.x,0,isoObj.z));
					var ps : Point = new Point(isoObj.x,isoObj.z);
					rec = new Rectangle(ps.x + Number(locatList[i]), ps.y+ Number(locatList[i + 1]), vo.tileSize, vo.tileSize);
					
					isoObj.floor.push(rec);
				}
			}
		}
		
		
		public function focusEntity():void
		{
			if(!curMouseObj) return;
			
			_eObj =	new Entity(curMouseObj);
			
			var dot : EntityDepthDot = new EntityDepthDot(curMouseObj);
		}
		
		public function KeyControl(keyCode:uint):void
		{
			if(!_eObj) return;
			
			_eObj.keyControl(keyCode);
		}
		
		/**
		 * 碰撞实体 
		 */		
		private function hitEntity():void
		{
			var objs:Array = world.objects;
			var isoObj : IsoObject;
			for(var i:int=0;i<objs.length;i++)
			{
				isoObj = objs[i];
				for(var j:int=0;j<isoObj.floor.length;j++)
				{
					
					var rec : Rectangle
					
					if(vo.mapType == 1 || vo.mapType == 2)
					{
						var p3 : Point3D = IsoUtils.screenToIso(new Point(world.mouseX, world.mouseY));
						rec  = isoObj.floor[j];
						if(rec)
						{
							if(rec.contains(p3.x,p3.z))
							{
								trace(isoObj.id);
							}
						}
					}
					else if (vo.mapType == 3)
					{
						var p : Point = new Point(world.mouseX, world.mouseY);
						rec  = isoObj.floor[j];
						if(rec)
						{
							if(rec.contains(p.x,p.y))
							{
								trace(isoObj.id);
							}
						}
					}
				
				}
			}
		}
		
		/**
		 * 时时更新 
		 */		
		public function update(evt : MouseEvent = null) : void
		{
			hitEntity();
		}
	}
}